package com.tbit.uqbike.service.business.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.github.pagehelper.PageHelper;
import com.tbit.common.entity.pojo.vo.DateResult;
import com.tbit.uqbike.constant.WorkType;
import com.tbit.uqbike.object.pojo.AccountUser;
import com.tbit.uqbike.object.pojo.Region;
import com.tbit.uqbike.object.pojo.WorkOrderVO;
import com.tbit.uqbike.object.pojo.dto.mainManage.BarChartWorkOrderDTO;
import com.tbit.uqbike.object.pojo.statistics.DispatchLog;
import com.tbit.uqbike.object.pojo.statistics.MoveLog;
import com.tbit.uqbike.object.pojo.statistics.PowerLogDetail;
import com.tbit.uqbike.object.pojo.statistics.RepairLog;
import com.tbit.uqbike.object.value.LoginInfo;
import com.tbit.uqbike.service.business.AccountUserService;
import com.tbit.uqbike.service.business.WorkOrderService;
import com.tbit.uqbike.webmanager.dao.core.AccountUserDao;
import com.tbit.uqbike.webmanager.dao.core.WorkOrderDao;
import com.tbit.uqbike.webmanager.dao.log.DispatchLogDao;
import com.tbit.uqbike.webmanager.dao.log.MoveLogDao;
import com.tbit.uqbike.webmanager.dao.log.PowerChangeLogDao;
import com.tbit.uqbike.webmanager.dao.log.RepairLogDao;
import com.tbit.uqbike.webmanager.util.PowerLogExportUtil;
import com.tbit.uqbike.webmanager.util.StringUtil;
import com.tbit.utils.DateTimeUtil;
import com.tbit.utils.NullUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @author ：hzw
 * @date ：Created in 2021/8/16 15:36
 * @description：
 * @modified By：
 * @version: $
 */
@Slf4j
@Service(value = "WorkOrderService")
public class WorkOrderServiceImpl implements WorkOrderService {
    @Autowired
    private WorkOrderDao workOrderDao;
    @Autowired
    private AccountUserDao accountUserDao;
    @Autowired
    private PowerChangeLogDao powerChangeLogDao;
    @Autowired
    private AccountUserService accountUserService;
    @Autowired
    private RepairLogDao repairLogDao;
    @Autowired
    private DispatchLogDao dispatchLogDao;
    @Autowired
    private MoveLogDao moveLogDao;

    @Override
    public List<List<DateResult>> statisticsByTime(BarChartWorkOrderDTO barChartWorkOrderDTO) {
        List<List<DateResult>> datalist = new ArrayList<>();
        Map<String, Object> map = new HashMap<>(12);
        map.put("accountId", barChartWorkOrderDTO.getAccountId());
        map.put("getUserId", barChartWorkOrderDTO.getAccountUserId());
        map.put("startTime", new Date(barChartWorkOrderDTO.getStartTime()));
        map.put("endTime", new Date(barChartWorkOrderDTO.getEndTime()));
        map.put("workType", barChartWorkOrderDTO.getWorkType());
        map.put("buildType", barChartWorkOrderDTO.getBuildType());
        map.put("locationType",barChartWorkOrderDTO.getLocationType());
        /**兼容审核状态字段*/
        List<Integer> validList = barChartWorkOrderDTO.getValidList();
        for (Integer valid : validList) {
            if (valid.equals(WorkType.workOrder_underReview)) {
                map.put("state", WorkType.workOrder_state_audit);
                validList.remove(valid);
                break;
            }
        }
        map.put("isValid", validList);
        //获取区域工单数据
        List<DateResult> data = workOrderDao.statisticsByTime(map);
        datalist.add(data);

        //获取运营区的所有分区id
        List<Region> list = accountUserDao.getRegionId(barChartWorkOrderDTO.getAccountId());
        //获取传入时间每天的日期
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        List<String> findTimeList = DateTimeUtil.findDaysStr(simpleDateFormat.format(new Date(barChartWorkOrderDTO.getStartTime())), simpleDateFormat.format(new Date(barChartWorkOrderDTO.getEndTime())));
        //查询区域统计数据
        //获取所有分区工单数据
        map.put("regionIds", list.stream().map(Region::getRegionId).collect(Collectors.toList()));
        List<DateResult> allRegionData = workOrderDao.statisticsByTimeAndRegionId(map);
        //转成map
        Map<Integer, List<DateResult>> regionMap = new HashMap<>();
        for (DateResult allRegionDatum : allRegionData) {
            List<DateResult> dateResults = regionMap.get(allRegionDatum.getRegionId());
            if (CollectionUtil.isEmpty(dateResults)){
                dateResults = new ArrayList<>();
                dateResults.add(allRegionDatum);
                regionMap.put(allRegionDatum.getRegionId(), dateResults);
            }else {
                dateResults.add(allRegionDatum);
            }
        }

        if (barChartWorkOrderDTO.getBuildType().equals(WorkType.buildType_SD)) {
            return datalist;
        } else {
            for (Region region : list) {
                List<DateResult> dateResults = CollectionUtil.isEmpty(regionMap.get(region.getRegionId())) ? new ArrayList<>() : regionMap.get(region.getRegionId());

                //获取查询数据的日期集合
                List<String> regionList = dateResults.stream().map(DateResult::getDate).collect(Collectors.toList());
                //得到传入时间和查询数据日期集合的差集
                List<String> reduceRegion = findTimeList.stream().filter(item -> !regionList.contains(item)).collect(Collectors.toList());
                //进行补0
                for (String date : reduceRegion) {
                    DateResult dateResult = new DateResult();
                    dateResult.setDate(date);
                    dateResult.setTotal(0);
                    dateResults.add(dateResult);
                }

                for (DateResult result : dateResults) {
                    result.setRegionId(region.getRegionId());
                    result.setRegionName(region.getRegionName());
                }

                //根据日期排序
                List<DateResult> sortData = dateResults.stream().sorted(Comparator.comparing(DateResult::getDate)).collect(Collectors.toList());

                datalist.add(sortData);
            }
        }
        return datalist;
    }

    @Override
    public List<WorkOrderVO> queryPage(Integer accountId, String userCode, Integer accountUserId, Long startTime, Long endTime,
                                       List<Integer> regionIdList, Integer workType, Integer buildType, List<Integer> validList, Integer locationType) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("userCode", userCode);
        map.put("getUserId", accountUserId);
        map.put("startTime", new Date(startTime));
        map.put("endTime", new Date(endTime));
        map.put("regionIds", regionIdList);
        map.put("workType", workType);
        map.put("buildType", buildType);
        map.put("locationType",locationType);
        /**兼容审核状态字段*/
        for (Integer valid : validList) {
            if (valid.equals(WorkType.workOrder_underReview)) {
                map.put("state", WorkType.workOrder_state_audit);
                validList.remove(valid);
                break;
            }
        }
        map.put("validList", validList);


        /**获取所有的运维人员*/
        List<AccountUser> list = accountUserService.getByType(accountId, false);
        Map<Integer, AccountUser> accountUserMap = new HashMap<>();
        if (list != null) {
            for (AccountUser accountUser : list) {
                accountUserMap.put(accountUser.getAccountUserId(), accountUser);
            }
        }
        /**获取条件符合的工单数据*/
        List<WorkOrderVO> workOrderList = workOrderDao.queryPage(map);
        /**拼接数据，如果在运维人员表没查到这个人员，则删除这条记录*/
        workOrderList.removeIf(workOrder -> {
            /**查询换电工单*/
            if (workType.equals(WorkType.workType_HD) && buildType.equals(WorkType.buildType_ZD)) {
                /**兼容审核中状态字段*/
                if (workOrder.getState().equals(WorkType.workOrder_state_audit)) {
                    workOrder.setIsValid(WorkType.workOrder_underReview);
                }
                PowerLogDetail powerLogDetail = this.powerChangeLogDao.getTimeById(workOrder.getBusinessNo());
                if (powerLogDetail != null) {
                    workOrder.setChangeTime(powerLogDetail.getChangeTime());
                    workOrder.setOldSoc(powerLogDetail.getOldSoc());
                    workOrder.setNewSoc(powerLogDetail.getNewSoc());
                    workOrder.setAccountUserId(powerLogDetail.getAccountUserId());
                    workOrder.setUserCode(powerLogDetail.getUserCode());

                }
            } else if ((workType.equals(WorkType.workType_NC) || (workType.equals(WorkType.workType_DU)) && buildType.equals(WorkType.buildType_ZD))) {
                MoveLog moveLog = this.moveLogDao.getTimeById(workOrder.getBusinessNo());
                DispatchLog dispatchLog = null;
                if (workType.equals(WorkType.workType_DU)){
                    //查询调度日志
                    dispatchLog = dispatchLogDao.getTimeById(workOrder.getBusinessNo());
                }
                if (null != moveLog && (workType.equals(WorkType.workType_NC))) {
                    workOrder.setAccountUserId(moveLog.getAccountUserId());
                    workOrder.setMachineId(moveLog.getMachineId());
                    workOrder.setAccountUserName(moveLog.getName());
                    workOrder.setMoveStartTime(moveLog.getStartTime());
                    workOrder.setMoveEndTime(moveLog.getEndTime());
                    workOrder.setMoveStartLat(moveLog.getStartLat());
                    workOrder.setMoveStartLon(moveLog.getStartLon());
                    workOrder.setMoveEndLat(moveLog.getEndLat());
                    workOrder.setMoveEndLon(moveLog.getEndLon());
                    workOrder.setMoveState(moveLog.getIsValid());
                    workOrder.setMoveRemark(moveLog.getRemark());
                    workOrder.setMoveParkPoint(moveLog.getParkPointName());
                    workOrder.setAccountUserId(moveLog.getAccountUserId());
                }else if ((workType.equals(WorkType.workType_DU)) && null != dispatchLog){
                    workOrder.setAccountUserId(dispatchLog.getAccountUserId());
                    workOrder.setMachineId(dispatchLog.getMachineId());
                    workOrder.setAccountUserName(dispatchLog.getName());
                    workOrder.setMoveStartTime(dispatchLog.getDispatchTime());
                    workOrder.setMoveEndTime(dispatchLog.getFinishTime());
                    if (null != moveLog){
                        workOrder.setMoveStartLat(moveLog.getStartLat());
                        workOrder.setMoveStartLon(moveLog.getStartLon());
                        workOrder.setMoveEndLat(moveLog.getEndLat());
                        workOrder.setMoveEndLon(moveLog.getEndLon());
                        workOrder.setMoveParkPoint(moveLog.getParkPointName());
                    }
                    workOrder.setMoveState(dispatchLog.getIsValid());
                    workOrder.setMoveRemark(dispatchLog.getRemark());

                    workOrder.setAccountUserId(dispatchLog.getAccountUserId());
                }
            } else {
                if (!workType.equals(WorkType.workType_WX) || !buildType.equals(WorkType.buildType_ZD)) {
                    if (null != workOrder.getPriority()) {
                        if (workOrder.getPriority().equals(WorkType.priority_First)) {
                            workOrder.setPriority("低优先级");
                        } else if (workOrder.getPriority().equals(WorkType.priority_Second)) {
                            workOrder.setPriority("中优先级");
                        } else if (workOrder.getPriority().equals(WorkType.priority_Third)) {
                            workOrder.setPriority("高优先级");
                        }
                    }
                    return false;
                }
                RepairLog repairLog = this.repairLogDao.getTimeById(workOrder.getBusinessNo());
                if (repairLog != null) {
                    workOrder.setAccountUserId(repairLog.getAccountUserId());
                    workOrder.setAccountUserName(repairLog.getUserName());
                    workOrder.setUserCode(repairLog.getUserCode());
                    workOrder.setRepairAddTime(repairLog.getAddTime());
                    workOrder.setRepairTime(repairLog.getAcceptTime());
                    workOrder.setRepairType(repairLog.getRepairTypes());
                    workOrder.setRepairRemark(repairLog.getRemark());
                    workOrder.setRepairState(repairLog.getRepairState());
                    workOrder.setRepairUrl(repairLog.getImageIds());
                }
            }

            if (accountUserMap != null
                    && null != accountUserMap.get(workOrder.getAccountUserId())
                    && (accountUserMap.get(workOrder.getAccountUserId())).getAccountUserId().equals(workOrder.getAccountUserId())) {
                workOrder.setAccountUserName((accountUserMap.get(workOrder.getAccountUserId())).getName());
                workOrder.setPhone((accountUserMap.get(workOrder.getGetUserId())).getPhone());
            }

            return false;
        });
        return workOrderList;
    }

    @Override
    public Integer queryCount(Integer accountId, String userCode, Integer accountUserId, Long startTime,
                              Long endTime, List<Integer> regionIdList, Integer workType, Integer buildType) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("userCode", userCode);
        map.put("getUserId", accountUserId);
        map.put("startTime", new Date(startTime));
        map.put("endTime", new Date(endTime));
        map.put("regionIds", regionIdList);
        map.put("workType", workType);
        map.put("buildType", buildType);
        return workOrderDao.queryCount(map);
    }

    @Override
    public List<WorkOrderVO> exportByTime(Integer accountId, String userCode, Integer accountUserId,
                                          Long startTime, Long endTime, List<Integer> regionIdList,
                                          Integer workType, Integer buildType, List<Integer> validList, Integer locationType) {
        Map<String, Object> map = new HashMap<>();
        map.put("accountId", accountId);
        map.put("userCode", userCode);
        map.put("getUserId", accountUserId);
        map.put("startTime", new Date(startTime));
        map.put("endTime", new Date(endTime));
        map.put("regionIds", regionIdList);
        map.put("workType", workType);
        map.put("buildType", buildType);
        map.put("locationType",locationType);
        /**兼容审核状态字段*/
        for (Integer valid : validList) {
            if (valid.equals(WorkType.workOrder_underReview)) {
                map.put("state", WorkType.workOrder_state_audit);
                validList.remove(valid);
                break;
            }
        }
        map.put("validList", validList);

        List<AccountUser> list = accountUserService.getByType(accountId, false);
        Map<Integer, AccountUser> accountUserMap = new HashMap<>();
        if (list != null) {
            for (AccountUser accountUser : list) {
                accountUserMap.put(accountUser.getAccountUserId(), accountUser);
            }
        }

        List<WorkOrderVO> workOrderList = workOrderDao.excelPage(map);

        workOrderList.removeIf(workOrder -> {
            /**查询换电工单*/
            if (workType.equals(WorkType.workType_HD) && buildType.equals(WorkType.buildType_ZD)) {
                /**审核人信息*/
                AccountUser auditUser = accountUserMap.get(workOrder.getAuditorId());
                if (!NullUtils.isEmpty(auditUser)) {
                    workOrder.setAuditName(auditUser.getName());
                }
                /**兼容审核中状态字段*/
                if (workOrder.getState().equals(WorkType.workOrder_state_audit)) {
                    workOrder.setIsValid(WorkType.workOrder_underReview);
                }
                PowerLogDetail powerLogDetail = this.powerChangeLogDao.getTimeById(workOrder.getBusinessNo());
                if (powerLogDetail != null) {
                    workOrder.setChangeTime(powerLogDetail.getChangeTime());
                    workOrder.setOldSoc(powerLogDetail.getOldSoc());
                    workOrder.setNewSoc(powerLogDetail.getNewSoc());
                    workOrder.setAccountUserId(powerLogDetail.getAccountUserId());
                    workOrder.setUserCode(powerLogDetail.getUserCode());
                }
            } else if ((workType.equals(WorkType.workType_NC) || workType.equals(WorkType.workType_DU)) && buildType.equals(WorkType.buildType_ZD)) {
                MoveLog moveLog = this.moveLogDao.getTimeById(workOrder.getBusinessNo());
                if (null != moveLog) {
                    workOrder.setAccountUserId(moveLog.getAccountUserId());
                    workOrder.setMachineId(moveLog.getMachineId());
                    workOrder.setAccountUserName(moveLog.getName());
                    workOrder.setMoveStartTime(moveLog.getStartTime());
                    workOrder.setMoveEndTime(moveLog.getEndTime());
                    workOrder.setMoveStartLat(moveLog.getStartLat());
                    workOrder.setMoveStartLon(moveLog.getStartLon());
                    workOrder.setMoveEndLat(moveLog.getEndLat());
                    workOrder.setMoveEndLon(moveLog.getEndLon());
                    workOrder.setMoveState(moveLog.getIsValid());
                    workOrder.setMoveRemark(moveLog.getRemark());
                    workOrder.setMoveParkPoint(moveLog.getParkPointName());
                    workOrder.setAccountUserId(moveLog.getAccountUserId());
                    if (workOrder.getIsValid() == 0){
                        workOrder.setIsValidList("无效");
                    }else if (workOrder.getIsValid() == 1){
                        workOrder.setIsValidList("有效");
                    }
                    if (workOrder.getLocationType() == 0){
                        workOrder.setAccountUserName("站外");
                    }else if (workOrder.getLocationType() == 1){
                        workOrder.setAccountUserName("站内");
                    }else if (workOrder.getLocationType() == 2){
                        workOrder.setAccountUserName("超区");
                    }
                }
                workOrder.transAddress();
            } else {
                if (!workType.equals(WorkType.workType_WX) || !buildType.equals(WorkType.buildType_ZD)) {
                    if (null != workOrder.getPriority()) {
                        if ("1".equals(workOrder.getPriority())) {
                            workOrder.setPriority("低优先级");
                        } else if ("2".equals(workOrder.getPriority())) {
                            workOrder.setPriority("中优先级");
                        } else if ("3".equals(workOrder.getPriority())) {
                            workOrder.setPriority("高优先级");
                        }
                    }

                    return false;
                }

                RepairLog repairLog = this.repairLogDao.getTimeById(workOrder.getBusinessNo());
                if (repairLog != null) {
                    workOrder.setAccountUserId(repairLog.getAccountUserId());
                    workOrder.setUserCode(repairLog.getUserCode());
                    workOrder.setRepairAddTime(repairLog.getAddTime());
                    workOrder.setRepairTime(repairLog.getAcceptTime());
                    workOrder.setRepairType(repairLog.getRepairTypes());
                    workOrder.setRepairRemark(repairLog.getRemark());
                    workOrder.setRepairState(repairLog.getRepairState());
                    workOrder.setRepairUrl(repairLog.getImageIds());
                    String[] types = repairLog.getRepairTypes().split(",");
                    StringBuilder str = new StringBuilder();

                    for (int i = 0; i < types.length; ++i) {
                        if (null != PowerLogExportUtil.map.get(Integer.parseInt(types[i]))) {
                            str.append(PowerLogExportUtil.map.get(Integer.parseInt(types[i])) + ",");
                        }
                    }

                    String s = str.toString();
                    if (!"".equals(s) && s.length() - 1 == s.lastIndexOf(",")) {
                        s = s.substring(0, s.length() - 1);
                    }

                    workOrder.setRepairTypes(s);
                    workOrder.setRepairStates(workOrder.getRepairState() == 1 ? "维修完成" : "未维修");
                }
            }

            if (accountUserMap != null && null != accountUserMap.get(workOrder.getAccountUserId()) && accountUserMap.get(workOrder.getAccountUserId()).getAccountUserId().equals(workOrder.getAccountUserId())) {
                workOrder.setAccountUserName(accountUserMap.get(workOrder.getAccountUserId()).getName());
                workOrder.setPhone(accountUserMap.get(workOrder.getAccountUserId()).getPhone());
            }

            return false;
        });
        return workOrderList;
    }

    @Override
    public List<WorkOrderVO> getByType(Integer accountId, Integer accountUserId, Long startTime,
                                       Long endTime, Integer rowCount, Integer pageNO,
                                       List<Integer> regionIdList, Integer type, Integer workType, Integer buildType, Integer locationType) {
        PageHelper.startPage(pageNO, rowCount);
        HashMap<String, Object> params = new HashMap<>();
        params.put("accountId", accountId);
        params.put("startTime", new Date(startTime));
        params.put("endTime", new Date(endTime));
        params.put("regionIds", regionIdList);
        params.put("workType", workType);
        params.put("buildType", buildType);
        params.put("pageNO", (pageNO - 1) * rowCount);
        params.put("rowCount", rowCount);
        params.put("locationType", locationType);
        List<WorkOrderVO> businessNoList = new ArrayList<>();
        if (type == 0) {
            businessNoList = workOrderDao.getBusinessNo(params);

            List<AccountUser> list = accountUserService.getByType(accountId, false);
            Map<Integer, AccountUser> map = new HashMap<>();
            if (list != null && list.size() > 0) {
                for (AccountUser accountUser : list) {
                    map.put(accountUser.getAccountUserId(), accountUser);
                }
            }
            if (!NullUtils.isEmpty(businessNoList)) {
                for (WorkOrderVO workOrderVO : businessNoList) {
                    TreeMap<String, Long> result = StringUtil.getListBySymbol(workOrderVO.getIsValidList());
                    /**封装不同类型的属性值*/
                    workOrderVO.setValid(Math.toIntExact(result.get(WorkType.workOrder_Valid.toString()) == null ? 0 : result.get(WorkType.workOrder_Valid.toString())));
                    workOrderVO.setUnValid(Math.toIntExact(result.get(WorkType.workOrder_UnValid.toString()) == null ? 0 : result.get(WorkType.workOrder_UnValid.toString())));

                    AccountUser accountUser = map.get(workOrderVO.getGetUserId());
                    if (accountUser != null) {
                        workOrderVO.setGetUserName(accountUser.getName());
                        workOrderVO.setGetUserPhone(accountUser.getPhone());
                    }
                    workOrderVO.setIsValidList(null);
                }
            }
        } else if (type == 1) {
            businessNoList = workOrderDao.getBusinessNoByRegion(params);
            /**查询某个运营区下所有的分区id*/
            List<Region> regionList = accountUserDao.getRegionId(accountId);
            Map<Integer, Region> regionMap = new HashMap<>();

            if (regionList != null && regionList.size() > 0) {
                for (Region region : regionList) {
                    regionMap.put(region.getRegionId(), region);
                }
            }
            for (WorkOrderVO workOrderVO : businessNoList) {
                Region region = regionMap.get(workOrderVO.getRegionId());
                if (region != null) {
                    workOrderVO.setRegionName(region.getRegionName());
                }
            }

        }
        return businessNoList;
    }

    @Override
    public void updateAudit(WorkOrderVO workOrderVO, LoginInfo loginInfo) {
        Date nowTime = new Date();

        List<AccountUser> list = accountUserService.getByType(workOrderVO.getAccountId(), false);

        Map<Integer, AccountUser> accountUserMap = new HashMap<>();
        if (list != null && list.size() > 0) {
            for (AccountUser accountUser : list) {
                accountUserMap.put(accountUser.getAccountUserId(), accountUser);
            }
        }
        /**审核人信息*/
        AccountUser auditUser = accountUserMap.get(loginInfo.accountUserId);
        if (!NullUtils.isEmpty(auditUser)) {
            workOrderVO.setAuditName(auditUser.getName());
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            workOrderVO.setRemark(workOrderVO.getRemark() + ";审核人:" + workOrderVO.getAuditName() + ";审核时间:" + simpleDateFormat.format(nowTime));
        }


        workOrderVO.setState(3);
        workOrderVO.setAuditorId(loginInfo.accountUserId);
        workOrderVO.setAuditTime(nowTime);
        workOrderDao.amendAuditState(workOrderVO);
        PowerLogDetail powerLogDetail = new PowerLogDetail();
        powerLogDetail.setIsValid(workOrderVO.getIsValid());
        /**根据换电工单查询换电记录*/
        PowerLogDetail logDetail = powerChangeLogDao.getTimeById(workOrderVO.getBusinessNo());
        if (!NullUtils.isEmpty(logDetail)) {
            powerLogDetail.setPowerChangeLogId(logDetail.getPowerChangeLogId());
        }
        /**换电记录审核状态和换电工单审核状态一致*/
        powerChangeLogDao.amendAuditState(powerLogDetail);

    }

    @Override
    public void amendAuditState(WorkOrderVO workOrderVO) {
        workOrderDao.amendAuditState(workOrderVO);
    }

    @Override
    public WorkOrderVO getDataById(Integer powerChangeLogId) {
        return workOrderDao.getDataById(powerChangeLogId);
    }
}
